import math

class Vector3f (object):

    def __init__ (self, x = 0.0, y = 0.0, z = 0.0):
        self.x = x
        self.y = y
        self.z = z

    def __sub__(self, other):
        x = other.x - self.x
        y = other.y - self.y
        z = other.z - self.z
        return Vector3f (x, y, z)

    def __add__ (self, other):
        x = other.x + self.x
        y = other.y + self.y
        z = other.z + self.z
        return Vector3f (x, y, z)

    def __iadd__ (self, other):
        self.x += other.x
        self.y += other.y
        self.z += other.z
        return self

    def __isub__ (self, other):
        self.x -= other.x
        self.y -= other.y
        self.z -= other.z
        return self

    def dot (self, other):
        x = self.x * other.x
        y = self.y * other.y
        z = self.z * other.z
        return x + y + z

    def __mul__ (self, other):
        if other.__class__ == Vector3f:
            return self.dot (other)
        x = self.x * other
        y = self.y * other
        z = self.z * other
        return Vector3f (x, y, z)

    def normalize (self):
        L = self.length ()
        if L == 0.0:
            return None
        return self * (1.0 / L)

    def clone (self):
        return Vector3f (self.x, self.y, self.z)

    def values (self):
        return self.x, self.y, self.z

    def length (self):
        return math.sqrt (self.x ** 2 + self.y ** 2 + self.z ** 2)

    def angleY (self):
        angle = math.asin (self.x) * 57.295779
        if self.z < 0.0:
            if self.x < 0.0: sign = -1
            else: sign = 1
            angle = sign * 180.0 - angle
        return angle

    def look_at (self, other):
        direction = (other - self).normalize ()
        if direction:
            return direction
        return self.normalize ()

    def __str__ (self):
        return "{Vector3f x:%f, y:%f, z:%f" % self.values ()